home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / jabber / JabberBuddy.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  19KB  |  519 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import common
  5. import hashlib
  6. import jabber
  7. from jabber import JID, Presence
  8. from util import callsback, Storage as S, cproperty, odict, threaded, urlcacheopen
  9. from common.actions import action
  10. from jabber.objects.nick import NICK_NS, Nick
  11. from common import pref
  12. from gui import skin
  13. from urllib import quote
  14. from pyxmpp.jabber.vcard import VCardString
  15.  
  16. VCardString.decode = lambda s, *a: s.value.decode(*a)
  17. from jabber import VCard
  18. from util.observe import ObservableProperty as oproperty
  19. import logging
  20. log = logging.getLogger('jabber.buddy')
  21. GTALK = 'gtalk'
  22. GTALK_DOMAINS = ('gmail.com', 'googlemail.com')
  23. JABBER = 'jabber'
  24.  
  25. def isGTalk(resource):
  26.     if not isinstance(resource, basestring):
  27.         return False
  28.     
  29.     reslower = resource.lower()
  30.     return (any,)((lambda .0: for x in .0:
  31. reslower.startswith(x))(('talk.', 'gmail.', 'talkgadget', 'ics')))
  32.  
  33.  
  34. no_widget = lambda self: None if getattr(self, 'iswidget', False) else True
  35. ADDRESS_KEYS = 'street,extadr,locality,region,pcode,ctry'.split(',')
  36. WORK_KEYS = 'company department postition role'.split()
  37. SUBSCRIPTION_TO = ('to', 'both')
  38. SUBSCRIPTION_FROM = ('from', 'both')
  39.  
  40. class JabberBuddy(common.buddy):
  41.     
  42.     def __init__(self, jabber_, jid, rosteritem = None):
  43.         uname = JID(jid).bare().as_unicode()
  44.         self.jid = JID(jid).bare()
  45.         self.username = uname
  46.         self.resources = { }
  47.         self.subscription = None if rosteritem else None
  48.         self.rostername = None if rosteritem else None
  49.         self.ask = None if rosteritem else None
  50.         self.groups = None if rosteritem else []
  51.         self.profile = False
  52.         common.buddy.__init__(self, uname, jabber_)
  53.         self._gen_pretty_profile()
  54.         self.pending_adds = set()
  55.  
  56.     
  57.     def __call__(self, item):
  58.         self.subscription = item.subscription
  59.         self.ask = item.ask
  60.         self.rostername = item.name
  61.         self.groups = item.groups
  62.         self.check_subscription()
  63.         return self
  64.  
  65.     
  66.     def sort(self, cmp = cmp, key = (lambda x: x), reverse = False):
  67.         pass
  68.  
  69.     
  70.     def check_subscription(self):
  71.         if self.subscription not in SUBSCRIPTION_TO and self.resources and self is not getattr(self.protocol, 'self_buddy', sentinel):
  72.             self.resources.clear()
  73.             self.notify()
  74.         
  75.  
  76.     
  77.     def service(self):
  78.         if self.jid.domain in GTALK_DOMAINS:
  79.             return GTALK
  80.         else:
  81.             return JABBER
  82.  
  83.     service = property(service)
  84.     
  85.     def serviceicon(self):
  86.         if self.jid.domain in GTALK_DOMAINS or any((lambda .0: for j in .0:
  87. isGTalk(j.resource))(self.resources)):
  88.             service = GTALK
  89.         else:
  90.             service = JABBER
  91.         return skin.get('serviceicons.' + service)
  92.  
  93.     serviceicon = property(serviceicon)
  94.     
  95.     def id(self):
  96.         return self.jid
  97.  
  98.     id = property(id)
  99.     
  100.     def away(self):
  101.         return None if self.service == GTALK else all((lambda .0: for r in .0:
  102. r.away)(self.resources.itervalues()))
  103.  
  104.     away = property(away)
  105.     
  106.     def mobile(self):
  107.         return False
  108.  
  109.     mobile = property(mobile)
  110.     
  111.     def blocked(self):
  112.         return False
  113.  
  114.     blocked = property(blocked)
  115.     
  116.     def online(self):
  117.         return bool(self.resources)
  118.  
  119.     online = property(online)
  120.     
  121.     def idle(self):
  122.         if self.service == GTALK:
  123.             if self.resources:
  124.                 pass
  125.             return all((lambda .0: for r in .0:
  126. r.idle)(self.resources.itervalues()))
  127.         else:
  128.             return False
  129.  
  130.     idle = property(idle)
  131.     
  132.     def get_caps(self):
  133.         caps = common.buddy.get_caps(self)
  134.         for r in self.resources.values():
  135.             res = r.jid.resource
  136.             if res and not isGTalk(res):
  137.                 break
  138.                 continue
  139.         
  140.         return caps
  141.  
  142.     caps = property(get_caps)
  143.     
  144.     def _gen_pretty_profile(self):
  145.         profile = odict()
  146.         ok = False
  147.         fullname = self.vcard_get('fn')
  148.         if fullname:
  149.             profile['Full Name:'] = fullname
  150.             ok = True
  151.         
  152.         mapping = {
  153.             'birthday': ('bday',),
  154.             'email_address': ('email', 'address'),
  155.             'phone': ('tel', 'number'),
  156.             'company': ('org', 'name'),
  157.             'department': ('org', 'unit'),
  158.             'postition': ('title',),
  159.             'role': ('role',) }
  160.         for key in ('birthday', 'email_address', 'phone'):
  161.             val = self.vcard_get(*mapping[key])
  162.             if val is not None:
  163.                 profile[key.replace('_', ' ').title() + ':'] = val
  164.                 ok = True
  165.                 continue
  166.         
  167.         homepage = self.vcard_get('url')
  168.         if homepage:
  169.             profile['Website'] = (homepage, homepage)
  170.             ok = True
  171.         
  172.         about = self.vcard_get('desc')
  173.         if about:
  174.             if ok:
  175.                 profile['sep1'] = 4
  176.             
  177.             profile['Additional Information:'] = ''.join([
  178.                 '\n',
  179.                 about])
  180.         
  181.         
  182.         def prettyaddy(addict):
  183.             addy = []
  184.             
  185.             add = lambda s: addy.insert(0, s)
  186.             mstr = '%(street)s %(extadr)s %(locality)s %(region)s %(pcode)s %(ctry)s' % addict
  187.             if isinstance(mstr, unicode):
  188.                 mstr = mstr.encode('utf-8')
  189.             
  190.             murl = 'http://maps.google.com/maps?q=' + quote(mstr)
  191.             if addict.ctry:
  192.                 add('\n' + addict.ctry)
  193.             
  194.             if addict.pcode:
  195.                 add(addict.pcode)
  196.             
  197.             if addict.region:
  198.                 if addict.pcode:
  199.                     add(' ')
  200.                 
  201.                 add(addict.region)
  202.             
  203.             if addict.locality:
  204.                 if addict.region or addict.pcode:
  205.                     add(', ')
  206.                 
  207.                 add(addict.locality)
  208.             
  209.             if addict.extadr:
  210.                 if any((addict.locality, addict.region, addict.pcode)):
  211.                     add('\n')
  212.                 
  213.                 add(addict.extadr)
  214.             
  215.             if addict.street:
  216.                 if any((addict.locality, addict.region, addict.pcode, addict.extadr)):
  217.                     add('\n')
  218.                 
  219.                 add(addict.street)
  220.             
  221.             if addy:
  222.                 add([
  223.                     '(',
  224.                     (murl, 'map'),
  225.                     ')\n'])
  226.             
  227.             return addy
  228.  
  229.         address = self.vcard_get('adr')
  230.         if ok:
  231.             profile['sep3'] = 4
  232.         
  233.         for key in WORK_KEYS:
  234.             val = self.vcard_get(*mapping[key])
  235.             profile[key.title() + ':'] = val
  236.         
  237.         self.last_pretty_profile = profile
  238.         return profile
  239.  
  240.     
  241.     def pretty_profile(self):
  242.         return getattr(self, ('last_pretty_profile',), (lambda : self._gen_pretty_profile()))
  243.  
  244.     pretty_profile = property(pretty_profile)
  245.     
  246.     def get_status_message(self):
  247.         
  248.         try:
  249.             res = self.get_highest_priority_resource()
  250.             if res:
  251.                 if not res.status_message:
  252.                     pass
  253.                 return ''
  254.             else:
  255.                 return ''
  256.         except Exception:
  257.             e = None
  258.             log.warning('status_message(self) on %r: %r', self, e)
  259.             raise 
  260.  
  261.  
  262.     
  263.     def set_status_message(self, value):
  264.         r = self.get_highest_priority_resource()
  265.         if r:
  266.             old = r.status_message
  267.             r.status_message = value
  268.             self.notify('status_message', old, value)
  269.         
  270.  
  271.     status_message = property(get_status_message, set_status_message)
  272.     
  273.     def stripped_msg(self):
  274.         return self.status_message
  275.  
  276.     stripped_msg = property(stripped_msg)
  277.     
  278.     def status(self):
  279.         if self.subscription not in SUBSCRIPTION_TO and self is not getattr(self.protocol, 'self_buddy', sentinel):
  280.             return 'unknown'
  281.         elif not getattr(self, 'resources', []):
  282.             return 'offline'
  283.         elif not self.away:
  284.             return 'available'
  285.         else:
  286.             return 'away'
  287.  
  288.     status = property(status)
  289.     
  290.     def update_presence(self, presence, notify = True, buddy = None):
  291.         if not presence.get_from():
  292.             pass
  293.         buddy = buddy
  294.         presence_type = presence.get_type()
  295.         if not presence_type or presence_type == 'available':
  296.             old_length = len(self.resources)
  297.             self.resources[buddy] = jabber.resource(self.protocol, buddy, presence)
  298.             children = presence.xmlnode.get_children()
  299.             nicks = jabber.jabber_util.xpath_eval(presence.xmlnode, 'n:nick', {
  300.                 'n': NICK_NS })
  301.             if nicks:
  302.                 self.nick = Nick(nicks[0]).nick
  303.             
  304.             if self.jid.domain not in pref('digsby.guest.domains', []):
  305.                 self.protocol.get_buddy_icon(self.name)
  306.             
  307.         elif presence_type == 'unavailable':
  308.             if buddy in self.resources:
  309.                 del self.resources[buddy]
  310.             
  311.         
  312.         if notify:
  313.             self.notify('status')
  314.         
  315.  
  316.     
  317.     def get_highest_priority_resource(self):
  318.         return None if getattr(self, 'resources', []) else None
  319.  
  320.     
  321.     def set_vcard(self, stanza):
  322.         log.info('incoming vcard for %s', self)
  323.         self._vcard_incoming = False
  324.         q = stanza.get_query()
  325.         if not q:
  326.             return None
  327.         
  328.         
  329.         try:
  330.             vc = self.vcard = jabber.VCard(q)
  331.         except ValueError:
  332.             pass
  333.  
  334.         self._incoming_icon(vc.photo)
  335.         self._gen_pretty_profile()
  336.  
  337.     
  338.     def set_vc(self, vcard):
  339.         self._vcard = vcard
  340.  
  341.     
  342.     def get_vc(self):
  343.         return self._vcard
  344.  
  345.     vcard = property(get_vc, set_vc)
  346.     _vcard = cproperty(None, (lambda o: None if o is not None else None), (lambda o: None if o is not None else None))
  347.     
  348.     def vcard_get(self, *stuffs):
  349.         if self.vcard:
  350.             stuff = stuffs[0]
  351.             stuffs = stuffs[1:]
  352.             thing = getattr(self.vcard, stuff, None)
  353.             if isinstance(thing, list) and thing:
  354.                 thing = thing[0]
  355.                 while stuffs:
  356.                     thing = getattr(thing, stuffs[0])
  357.                     stuffs = stuffs[1:]
  358.             elif thing:
  359.                 if stuffs:
  360.                     log.warning_s('%r', stuffs)
  361.                     log.warning_s(self.vcard.as_xml())
  362.                 
  363.             
  364.             return None if thing else thing
  365.         
  366.  
  367.     nick = cproperty(None)
  368.     
  369.     def _incoming_icon(self, photos):
  370.         if photos and photos[0].image:
  371.             img = photos[0].image
  372.             self._update_photo_image(img)
  373.         elif photos and photos[0].uri:
  374.             
  375.             def success(result):
  376.                 (_response, content) = result
  377.                 self._update_photo_image(content)
  378.  
  379.             meth = threaded(urlcacheopen)
  380.             meth.verbose = False
  381.             meth(photos[0].uri, success = success)
  382.         
  383.  
  384.     
  385.     def _update_photo_image(self, data):
  386.         hash = hashlib.sha1(data).hexdigest()
  387.         self.cache_icon(data, hash)
  388.         self.icon_hash = hash
  389.  
  390.     
  391.     def get_remote_alias(self):
  392.         for attr in ('rostername', 'nick'):
  393.             nick = getattr(self, attr, None)
  394.             if nick:
  395.                 return unicode(nick)
  396.                 continue
  397.         
  398.         for attr in ('nickname', 'fn'):
  399.             nick = self.vcard_get(attr)
  400.             if nick:
  401.                 return unicode(nick)
  402.                 continue
  403.         
  404.  
  405.     remote_alias = oproperty(get_remote_alias, observe = [
  406.         'vcard'])
  407.     
  408.     def add_to_group(self, groupname, callback = None):
  409.         log.info('%s add_to_group %s', self, groupname)
  410.         pending = self.pending_adds
  411.         if groupname in pending:
  412.             log.info('ignoring request.')
  413.         else:
  414.             pending.add(groupname)
  415.         item = self.protocol.roster.get_item_by_jid(self.id).clone()
  416.         if groupname not in item.groups:
  417.             item.groups.append(groupname)
  418.             query = item.make_roster_push()
  419.             
  420.             def onsuccess(_s):
  421.                 pending.discard(groupname)
  422.                 callback.success()
  423.  
  424.             
  425.             def onerror(_s = (None, (None, None, None), None)):
  426.                 pending.discard(groupname)
  427.                 log.warning('error adding %r to %s', self.id, groupname)
  428.  
  429.             self.protocol.send_cb(query, success = onsuccess, error = onerror, timeout = onerror)
  430.         
  431.  
  432.     add_to_group = action(needs = ((unicode, 'Group name'),))(callsback(add_to_group))
  433.     
  434.     def remove(self, callback = None):
  435.         
  436.         try:
  437.             item = self.protocol.roster.get_item_by_jid(self.id).clone()
  438.         except KeyError:
  439.             return None
  440.  
  441.         item.subscription = 'remove'
  442.         self.protocol.send_cb(item.make_roster_push(), callback = callback)
  443.  
  444.     remove = action()(callsback(remove))
  445.     
  446.     def subscribed(self):
  447.         self.protocol.send_presence(Presence(to_jid = self.id, stanza_type = 'subscribed'))
  448.  
  449.     subscribed = action((lambda self: if no_widget(self) is None:
  450. passelif self.subscription in SUBSCRIPTION_FROM:
  451. passTrue))(subscribed)
  452.     
  453.     def unsubscribed(self):
  454.         self.protocol.send_presence(Presence(to_jid = self.id, stanza_type = 'unsubscribed'))
  455.  
  456.     unsubscribed = action((lambda self: if no_widget(self) is None:
  457. passelif self.subscription not in SUBSCRIPTION_FROM:
  458. passTrue))(unsubscribed)
  459.     
  460.     def subscribe(self):
  461.         self.protocol.send_presence(Presence(to_jid = self.id, stanza_type = 'subscribe'))
  462.  
  463.     subscribe = action((lambda self: if no_widget(self) is None:
  464. passelif self.subscription in SUBSCRIPTION_TO:
  465. passTrue))(subscribe)
  466.     
  467.     def unsubscribe(self):
  468.         self.protocol.send_presence(Presence(to_jid = self.id, stanza_type = 'unsubscribe'))
  469.  
  470.     unsubscribe = action((lambda self: if no_widget(self) is None:
  471. passelif self.subscription not in SUBSCRIPTION_TO:
  472. passTrue))(unsubscribe)
  473.     
  474.     def appear_offline_to(self):
  475.         self.protocol.send_presence(Presence(stanza_type = 'unavailable', status = 'Logged Out', to_jid = self.id))
  476.  
  477.     
  478.     def expand(self):
  479.         print 'expand %r' % self
  480.  
  481.     expand = action()(expand)
  482.     
  483.     def sorted_resources(self):
  484.         return sorted(self.resources.itervalues(), key = (lambda r: (r.priority, r.jid)), reverse = True)
  485.  
  486.     
  487.     def __iter__(self):
  488.         return iter(self.sorted_resources())
  489.  
  490.     
  491.     def __len__(self):
  492.         return len(self.resources)
  493.  
  494.     
  495.     def __getitem__(self, index):
  496.         return self.sorted_resources()[index]
  497.  
  498.     
  499.     def __repr__(self):
  500.         
  501.         try:
  502.             res = len(self.resources)
  503.         except:
  504.             res = 0
  505.  
  506.         
  507.         try:
  508.             n = self.name
  509.         except:
  510.             n = ''
  511.  
  512.         return '<JabberBuddy %s %d>' % (n, res)
  513.  
  514.  
  515.  
  516. def dupe_presence(p):
  517.     return Presence(p.get_node())
  518.  
  519.